package cn.swing.ui;
import cn.configure.QRContentsParamsConfigure;
import cn.configure.SettingConfigure;
import cn.utils.MessageBoxUtil;
import cn.utils.QRUtils;
import cn.utils.excelutil.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.google.zxing.WriterException;
import lombok.Data;
import lombok.Getter;

import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
 * @author xbsoft2
 */
@Getter
public final class QR {
  public QR() {
    // initComponent();
    initValue();
    initListener();
  }
  private QRContentsParamsConfigure configure;
  private SettingConfigure settingConfigure;
  private JPanel rootPanel;
  private JPanel subPanel;
  private JButton setting;
  private JButton create;
  private JTextField url;
  private JCheckBox isEnableUrl;
  private JTextField key1;
  private JTextField value1;
  private JCheckBox isEnable1;
  private JTextField key2;
  private JTextField value2;
  private JCheckBox isEnable2;
  private JTextField key3;
  private JTextField value3;
  private JCheckBox isEnable3;
  private JTextField key4;
  private JTextField value4;
  private JCheckBox isEnable4;
  private JTextField key5;
  private JTextField value5;
  private JCheckBox isEnable5;
  private JTextField key6;
  private JSpinner startNum;
  private JSpinner endNum;
  private JCheckBox isText;
  private JCheckBox isEnable6;
  private JTextField key7;
  private JSpinner startPort;
  private JSpinner endPort;
  private JCheckBox isSuffix;
  private JCheckBox isEnable7;
  private JSlider currentNum;
  private JLabel currentNumText;
  private JLabel total;
  private JComboBox<Integer> timeSpacing;
  private JCheckBox readExcelCheckBox;
  private JCheckBox readTxtCheckBox;
  private void initComponent() {
    rootPanel = new JPanel();
    subPanel = new JPanel();
    setting = new JButton();
    create = new JButton();
    url = new JTextField();
    isEnableUrl = new JCheckBox();
    key1 = new JTextField();
    value1 = new JTextField();
    isEnable1 = new JCheckBox();
    key2 = new JTextField();
    value2 = new JTextField();
    isEnable2 = new JCheckBox();
    key3 = new JTextField();
    value3 = new JTextField();
    isEnable3 = new JCheckBox();
    key4 = new JTextField();
    value4 = new JTextField();
    isEnable4 = new JCheckBox();
    key5 = new JTextField();
    value5 = new JTextField();
    isEnable5 = new JCheckBox();
    key6 = new JTextField();
    startNum = new JSpinner();
    endNum = new JSpinner();
    isText = new JCheckBox();
    isEnable6 = new JCheckBox();
    key7 = new JTextField();
    startPort = new JSpinner();
    endPort = new JSpinner();
    isSuffix = new JCheckBox();
    isEnable7 = new JCheckBox();
    currentNum = new JSlider();
    currentNumText = new JLabel();
    total = new JLabel();
    timeSpacing = new JComboBox<>();
  }
  /**
   * 1/2、初始化参数默认值
   */
  private void initValue() {
    try {
      configure = QRContentsParamsConfigure.get();
      settingConfigure = SettingConfigure.getSettingConfigure();
      timeSpacing.addItem(0);
      for (int i = 100; i <= 10000; i += 100) {
        timeSpacing.addItem(i);
      }
      url.setText(configure.getUrl());
      isEnableUrl.setSelected(configure.getIsEnableUrl());
      key1.setText(configure.getKey1());
      value1.setText(configure.getValue1());
      isEnable1.setSelected(configure.getIsEnable1());
      key2.setText(configure.getKey2());
      value2.setText(configure.getValue2());
      isEnable2.setSelected(configure.getIsEnable2());
      key3.setText(configure.getKey3());
      value3.setText(configure.getValue3());
      isEnable3.setSelected(configure.getIsEnable3());
      key4.setText(configure.getKey4());
      value4.setText(configure.getValue4());
      isEnable4.setSelected(configure.getIsEnable4());
      key5.setText(configure.getKey5());
      value5.setText(configure.getValue5());
      isEnable5.setSelected(configure.getIsEnable5());
      key6.setText(configure.getKey6());
      startNum.setValue(configure.getStartNum());
      endNum.setValue(configure.getEndNum());
      isText.setSelected(configure.getIsText());
      isEnable6.setSelected(configure.getIsEnable6());
      key7.setText(configure.getKey7());
      startPort.setValue(configure.getStartPort());
      endPort.setValue(configure.getEndPort());
      isSuffix.setSelected(configure.getIsSuffix());
      isEnable7.setSelected(configure.getIsEnable7());
      timeSpacing.setSelectedItem(configure.getTimeSpacing());
    }
    catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
      new Error("初始化参数默认值错误:\n" + e.getMessage());
    }
  }
  /**
   * 2/2、初始化监听器
   */
  private void initListener() {
    setting.addActionListener(e -> new Setting().setVisible(Boolean.TRUE));
    create.addActionListener(e -> Create());
    readExcelCheckBox.addActionListener(e -> readExcelCheckBoxEvent());
    readTxtCheckBox.addActionListener(e -> readTxtCheckBoxEvent());
  }
  private void readTxtCheckBoxEvent() {
    if (!readTxtCheckBox.isSelected()) {
      readTxtCheckBox.setEnabled(Boolean.FALSE);
      readExcelCheckBox.setEnabled(Boolean.TRUE);
    }
    else {
      readExcelCheckBox.setEnabled(Boolean.FALSE);
    }
  }
  private void readExcelCheckBoxEvent() {
    if (!readExcelCheckBox.isSelected()) {
      readExcelCheckBox.setEnabled(Boolean.FALSE);
      readTxtCheckBox.setEnabled(Boolean.TRUE);
    }
    else {
      readTxtCheckBox.setEnabled(Boolean.FALSE);
    }
  }
  /**
   * 创建
   */
  private void Create() {
    create.setEnabled(Boolean.FALSE);
    new Thread(() -> {
      // 保存参数
      sava();
      // 二维码内容集合(二维码内容，文字，文字后缀，文件名)
      List<QRContentItem> list = getQRList();
      if (list.isEmpty()) {
        MessageBoxUtil.showMsgBox("没有需要生成的内容,祝您生活愉快!");
        return;
      }
      // 遍历集合生成二维码
      createQR(list);
      // 弹出完成框
      new Info("OK\n" + "文件目录:" + new File(settingConfigure.getSaveSetting().getDirectory()).getAbsolutePath());
      create.setEnabled(Boolean.TRUE);
    }).start();
  }
  /**
   * 保存参数
   */
  private void sava() {
    configure.setUrl(url.getText());
    configure.setIsEnableUrl(isEnableUrl.isSelected());
    configure.setKey1(key1.getText());
    configure.setValue1(value1.getText());
    configure.setIsEnable1(isEnable1.isSelected());
    configure.setKey2(key2.getText());
    configure.setValue2(value2.getText());
    configure.setIsEnable2(isEnable2.isSelected());
    configure.setKey3(key3.getText());
    configure.setValue3(value3.getText());
    configure.setIsEnable3(isEnable3.isSelected());
    configure.setKey4(key4.getText());
    configure.setValue4(value4.getText());
    configure.setIsEnable4(isEnable4.isSelected());
    configure.setKey5(key5.getText());
    configure.setValue5(value5.getText());
    configure.setIsEnable5(isEnable5.isSelected());
    configure.setKey6(key6.getText());
    configure.setStartNum(Integer.valueOf(startNum.getValue().toString()));
    configure.setEndNum(Integer.valueOf(endNum.getValue().toString()));
    configure.setIsText(isText.isSelected());
    configure.setIsEnable6(isEnable6.isSelected());
    configure.setKey7(key7.getText());
    configure.setStartPort(Integer.valueOf(startPort.getValue().toString()));
    configure.setEndPort(Integer.valueOf(endPort.getValue().toString()));
    configure.setIsSuffix(isSuffix.isSelected());
    configure.setIsEnable7(isEnable7.isSelected());
    configure.setTimeSpacing(Integer.valueOf(timeSpacing.getSelectedItem().toString()));
    try {
      QRContentsParamsConfigure.save();
    }
    catch (IOException e) {
      e.printStackTrace();
      new Error("保存参数失败:\n" + e.getMessage());
    }
  }
  /**
   * 获取要生成的二维码数据集合
   *
   * @return 二维码数据集合
   */
  private List<QRContentItem> getQRList() {
    System.out.println("configure = " + configure);
    System.out.println("configure = " + JSON.toJSONString(configure));
    System.out.println("ReadExcelCheckBox = " + readExcelCheckBox.isSelected());
    System.out.println("ReadTxtCheckBox = " + readTxtCheckBox.isSelected());
    List<QRContentItem> list = new ArrayList<>();
    StringBuilder contentsBase = new StringBuilder();
    if (configure.getIsEnableUrl()) {
      contentsBase.append(configure.getUrl()).append("?");
    }
    if (configure.getIsEnable1()) {
      contentsBase.append(configure.getKey1()).append("=").append(configure.getValue1()).append("&");
    }
    if (configure.getIsEnable2()) {
      contentsBase.append(configure.getKey2()).append("=").append(configure.getValue2()).append("&");
    }
    if (configure.getIsEnable3()) {
      contentsBase.append(configure.getKey3()).append("=").append(configure.getValue3()).append("&");
    }
    if (configure.getIsEnable4()) {
      contentsBase.append(configure.getKey4()).append("=").append(configure.getValue4()).append("&");
    }
    if (configure.getIsEnable5()) {
      contentsBase.append(configure.getKey5()).append("=").append(configure.getValue5()).append("&");
    }
    if (configure.getIsEnable6()) {
      contentsBase.append(configure.getKey6()).append("=");
      // excel 读取
      if (readExcelCheckBox.isSelected()) {
        FileSystemView fsv = FileSystemView.getFileSystemView();
        JFileChooser fileChooser2 = new JFileChooser();
        fileChooser2.setCurrentDirectory(fsv.getHomeDirectory());
        fileChooser2.setDialogTitle("请选择您的excel的位置");
        if (JFileChooser.APPROVE_OPTION == fileChooser2.showOpenDialog(null)) {
          File f = fileChooser2.getSelectedFile();
          ExcelUtil excelUtil = new ExcelUtil();
          List<List<Object>> deviceNumList = excelUtil.read(f);
          for (List<Object> deviceNumInteger : deviceNumList) {
            System.out.println("deviceNumInteger = " + deviceNumInteger);
            Integer deviceNum = Integer.parseInt(String.valueOf(deviceNumInteger).replace("[", "").replace("]", ""));
            System.out.println("deviceNum = " + deviceNum);
            QRContentItem item = new QRContentItem();
            item.setContents(contentsBase.toString() + deviceNum);
            if (configure.getIsText()) {
              item.setText(String.valueOf(deviceNum));
            }
            item.setFileName(deviceNum + "");
            list.add(item);
          }
        }
        else {
          MessageBoxUtil.showMsgBox("为选择任何文件:excel");
        }
      }
      // txt 读取 暂时未实现
      else if (readTxtCheckBox.isSelected()) {
        // TODO
        MessageBoxUtil.showMsgBox("未实现的功能");
      }
      // 连续
      else {
        for (int num = configure.getStartNum(); num <= configure.getEndNum(); num++) {
          if (configure.getIsEnable7()) {
            for (int p = configure.getStartPort(); p <= configure.getEndPort(); p++) {
              QRContentItem item = new QRContentItem();
              item.setContents(contentsBase.toString() + num + "&" + configure.getKey7() + "=" + p);
              if (configure.getIsText()) {
                item.setText(String.valueOf(num));
              }
              if (configure.getIsSuffix()) {
                item.setSuffix("." + p);
              }
              item.setFileName(num + "-" + p);
              list.add(item);
            }
          }
          else {
            QRContentItem item = new QRContentItem();
            item.setContents(contentsBase.toString() + num);
            if (configure.getIsText()) {
              item.setText(String.valueOf(num));
            }
            item.setFileName(num + "");
            list.add(item);
          }
        }
      }
    }
    else {
      QRContentItem item = new QRContentItem();
      if (contentsBase.length() > 0) {
        contentsBase.deleteCharAt(contentsBase.length() - 1);
      }
      item.setContents(contentsBase.toString());
      list.add(item);
    }
    return list;
  }
  /**
   * 创建二维码
   *
   * @param list 二维码数据集合
   */
  private void createQR(List<QRContentItem> list) {
    currentNum.setValue(0);
    currentNum.setMaximum(list.size());
    currentNumText.setText("0");
    total.setText(currentNum.getMaximum() + "");
    int index = 0;
    for (QRContentItem item : list) {
      try {
        Thread.sleep(Integer.parseInt(Objects.requireNonNull(timeSpacing.getSelectedItem()).toString()));
      }
      catch (InterruptedException e) {
        MessageBoxUtil.showMsgBox(e.getMessage());
        new Error("生成二维码错误:\n" + e.getMessage());
        System.err.println(e.getMessage());
      }
      if ((item.getContents() != null) && (!item.getContents().isEmpty())) {
        settingConfigure.getQrCodeSetting().setContents(item.getContents());
      }
      if ((item.getText() != null) && (!item.getText().isEmpty())) {
        settingConfigure.getTextSetting().setContents(item.getText());
      }
      if ((item.getSuffix() != null) && (!item.getSuffix().isEmpty())) {
        settingConfigure.getTextSetting().setSuffix(item.getSuffix());
      }
      if ((item.getFileName() != null) && (!item.getFileName().isEmpty())) {
        settingConfigure.getSaveSetting().setFileName(item.getFileName());
      }
      try {
        QRUtils.generateQR();
      }
      catch (WriterException | IOException | ClassNotFoundException | RuntimeException e) {
        MessageBoxUtil.showMsgBox(e.getMessage());
        new Error("生成二维码错误:\n" + e.getMessage());
      }
      index++;
      currentNum.setValue(index);
      currentNumText.setText(index + "");
    }
  }
  @Data
  class QRContentItem implements Serializable {
    public static final long serialVersionUID = 1L;
    /**
     * 二维码内容
     */
    private String contents;
    /**
     * 二维码显示文字
     */
    private String text;
    /**
     * 文字后缀
     */
    private String suffix;
    /**
     * 保存文件名
     */
    private String fileName;
  }
}
